%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% none
%
%==========================================================================

%==========================================================================
% The function "loadPresetsToProject" loads a project structure from a
% given .mat project file into a new or existing project. Any field found
% in both the existing and the loaded project structures attains its value
% from the loaded project structure. Any field found only in the existing
% project is kept as it is. Any field found only in the loaded project is
% added to the existing project.In case of an existing project with
% properly set project file name, the final state of the project structure
% is saved to a project file with the specified name.
% INPUT: "presetsFileName" is a string specifying a .mat project file
% holding a single project structure of presets to be loaded into a new or
% existing project. 
% "inProjectStruct" is an optional project structure to be loaded with the 
% presets read from the specified file.
% OUTPUT: "projectStruct" returns the new or modified project structure
% loaded with the presets read from the specified file.
%==========================================================================
function projectStruct = loadPresetsToProject(presetsFileName, inProjectStruct)

factoryPresetsFileName = 'factoryPresets.mat';

if (nargin < 1)
    % Load the factory presets.
    load(factoryPresetsFileName);
    
% Check if the specified presets file exists.
elseif (exist(presetsFileName, 'file') ~= 2)
    warndlg('SoundRestoration:loadPresetsToProject:GivenPresetsFileDoesNotExist', ...
        'The given presets file does not exist.');
    
    % Load the factory presets.
    load(factoryPresetsFileName);
    
% Check if the specified file is a .mat file.
elseif (strcmpi(presetsFileName((end - 3):end), '.mat') == false)
    warndlg('Invalid presets file supplied. Using the factory presets instead.');
    
    % Load the factory presets.
    load(factoryPresetsFileName);
    
else
    % Load the specified presets file.
    load(presetsFileName);
    
    % Check if the loaded structure appears to be a presets structure.
    if (exist('projectStruct', 'var') ~= 1)
        warndlg('SoundRestoration:loadPresetsToProject:SourceIsNotValidProjectFile', ...
            'Specified source is not a valid project file. It does not load a structure called "projectStruct".');
        
        % Load the factory presets.
        load(factoryPresetsFileName);
    end
end

% If an existing project structure is not supplied, then the loaded
% structure is all that needs to be returned.
if (nargin < 2)
    return;
end

%==========================================================================
% If an existing project structure is supplied, then it has to be updated
% with the fields of the loaded structure before being returned. Note that
% any of the calls to "load" above should result in loading a project
% structure named "projectStruct".
%==========================================================================
% Find all fields of the given project structure that are not present in
% the loaded project structure.
missingFieldsCellArr = setdiff(fieldnames(inProjectStruct), fieldnames(projectStruct));

% Endow the loaded project structure with all fields found only in the
% given project structure.
for k = 1:numel(missingFieldsCellArr)
    projectStruct.(missingFieldsCellArr{k}) = inProjectStruct.(missingFieldsCellArr{k});
end

% If the project existed before this function call and has a properly set
% project file name, then save its current state.
if (isfield(inProjectStruct, 'projectFileName') == true)
    % Save the current state of the project structure to a project file.
    save(projectStruct.projectFileName, 'projectStruct');
end

return;
% end of the function "loadPresetsToProject"
